<?php

namespace Upfor\UpforPHP;

/**
 * Abstract Controller
 */
abstract class Controller {

    /**
     * Current controller
     *
     * @var string
     */
    protected $controller;

    /**
     * Current action
     *
     * @var string
     */
    protected $action;

    /**
     * View instance
     *
     * @var object
     */
    protected $viewObj;

    public function __construct() {
        $this->viewObj = view();

        $this->controller = request()->getController();
        $this->action = request()->getAction();
    }

    /* ***********************************************
     * View 相关公共方法
     * ***********************************************/

    /**
     * 输出页面
     *
     * @param array   $data
     * @param boolean $independent
     * @param string  $tplFile
     */
    public function view($data = array(), $independent = false, $tplFile = null) {
        if (!$tplFile) {
            $tplFile = $this->controller . '/' . $this->action;
        }

        if ($independent) {
            $this->viewObj->display($tplFile, $data);
        } else {
            $this->viewObj->set('tplFile', $tplFile);
            $this->viewObj->display('index', $data);
        }

        exit();
    }

    /**
     * 设置标题信息
     *
     * @param string $title
     */
    public function setTitle($title) {
        $this->viewObj->set('title', $title);
    }

    /**
     * 赋值模板变量
     *
     * @param string $varName
     * @param mixed  $value
     */
    public function assign($varName, $value) {
        $this->viewObj->set($varName, $value);
    }

    /**
     * 设置JS资源列表
     *
     * @param array $jsList
     */
    public function setJsResource(array $jsList) {
        $this->viewObj->set('jsResourceList', array_unique(array_merge((array) $this->viewObj->get('jsResourceList'), array_values($jsList))));
    }

    /**
     * 设置CSS资源列表
     *
     * @param array $cssList
     */
    public function setCssResource(array $cssList) {
        $this->viewObj->set('cssResourceList', array_unique(array_merge((array) $this->viewObj->get('cssResourceList'), array_values($cssList))));
    }

    /* ***********************************************
     * API接口 相关公共方法
     * ***********************************************/

    /**
     * 成功返回
     *
     * @param mixed $data
     */
    public function success($data = array(), $msg = '') {
        $this->response($data, 0, $msg ? : '请求成功');
    }

    /**
     * 失败返回
     *
     * @param integer $code
     * @param string  $msg
     */
    public function error($code, $msg = '') {
        $this->response([], $code, $msg);
    }

    /**
     * 返回数据
     *
     * @param mixed   $data 数据
     * @param integer $code 返回码
     * @param string  $msg  提示信息
     * @param string  $type 返回类型
     */
    protected function response($data, $code = 0, $msg = '', $type = 'json') {
        $responseData = array(
            'code' => $code,
            'data' => $data,
            'msg' => $msg,
        );
        $type = strtolower($type);

        if (request()->isAjax() || $type == 'json') {
            $this->ajaxReturn($responseData, 'json');
        } elseif (isset($_GET['callback'])) {
            $this->ajaxReturn($responseData, 'jsonp');
        } elseif ($type == 'dump') {
            echo '<pre>';
            var_dump($responseData);
            exit;
        } else {
            $this->ajaxReturn($responseData, 'json');
        }
    }

    /**
     * Ajax方式返回数据到客户端
     *
     * @param  mixed  $data 要返回的数据
     * @param  string $type AJAX返回数据格式
     * @return void
     */
    protected function ajaxReturn($data, $type = 'JSON') {
        ob_clean(); //清空输出缓冲区

        switch (strtoupper($type)) {
            case 'JSONP':
                // 返回JSON数据格式到客户端 包含状态信息
                response()->header('Content-Type', 'application/json; charset=utf-8');
                $handler = $_GET['callback'];
                $data = $handler . '(' . json_encode($data) . ');';
                break;
            case 'EVAL' :
                // 返回可执行的js脚本
                response()->header('Content-Type', 'text/html; charset=utf-8');
                break;
            default     :
            case 'JSON' :
                // 返回JSON数据格式到客户端 包含状态信息
                response()->header('Content-Type', 'application/json; charset=utf-8');
                $data = json_encode($data);
                break;
        }

        response()->body($data, true);
        response()->send();

        exit();
    }

}
